package org.bluesky.framework.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.bluesky.framework.dto.AddArticleDto;
import org.bluesky.framework.dto.ArticleDto;
import org.bluesky.framework.entity.ArticleTag;
import org.bluesky.framework.mapper.ArticleMapper;
import org.bluesky.framework.service.ArticleService;
import org.bluesky.framework.ResponseResult;
import org.bluesky.framework.constants.SystemConstants;
import org.bluesky.framework.entity.Article;
import org.bluesky.framework.entity.Category;
import org.bluesky.framework.service.ArticleTagService;
import org.bluesky.framework.service.CategoryService;
import org.bluesky.framework.utils.BeanCopyUtils;
import org.bluesky.framework.utils.RedisCache;
import org.bluesky.framework.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {

    @Autowired
    private CategoryService categoryService;
    @Autowired
    private RedisCache redisCache;

    @Autowired
    private ArticleTagService articleTagService;

    @Autowired
    private  ArticleMapper articleMapper;

    @Override
    public ResponseResult hotArticleList() {
        //查询热门文章，封装成ResponseResult返回
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        //必须是正式文章
        queryWrapper.eq(Article::getStatus, SystemConstants.ARTICLE_STATUS_NORMAL);
        queryWrapper.orderByDesc(Article::getViewCount);
        //分页查询
        Page<Article> page = new Page<>(SystemConstants.HOT_CURRENT_PAGE,SystemConstants.HOT_ARTICLE_NUMBER);
        page(page,queryWrapper);
        List<Article> articleList = page.getRecords();
        //从redis获取viewCount
        List<Article> articles = articleList.stream()
                .peek(article ->{
                    Integer count = redisCache.getCacheMapValue(SystemConstants.REDIS_VIEW_COUNT_KEY, article.getId().toString());
                    article.setViewCount(count.longValue());
                })
                .collect(Collectors.toList());
        //部分拷贝
//        List<HotArticleVo> hotArticleVos = new ArrayList<>();
//        for (Article article : articleList) {
//            HotArticleVo vo = new HotArticleVo();
//            BeanUtils.copyProperties(article,vo);
//            hotArticleVos.add(vo);
//        }
        List<HotArticleVo> hotArticleVos = BeanCopyUtils.copyBeanList(articles, HotArticleVo.class);
        return ResponseResult.okResult(hotArticleVos);
    }

    //文章列表查询
    @Override
    public ResponseResult articleList(Integer pageNum, Integer pageSize, Long categoryId) {
        //查询条件
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        //有categoryId就需要查询传入的相同
        queryWrapper.eq(Objects.nonNull(categoryId) && (categoryId > 0),Article::getCategoryId,categoryId);
        //状态是正式发布文章
        queryWrapper.eq(Article::getStatus,SystemConstants.ARTICLE_STATUS_NORMAL);
        //置顶文章：isTop字段降序排序
        queryWrapper.orderByDesc(Article::getIsTop);
        //分页查询
        Page<Article> page = new Page<>(pageNum,pageSize);
        page(page,queryWrapper);

        //查询categoryName
        List<Article> articles = page.getRecords();
        System.out.println(articles);
        //通过categoryId获取categoryName
//        for (Article article : articles) {
//            Category category = categoryService.getById(article.getCategoryId());
//            article.setCategoryName(category.getName());
//        }
        //stream流解决
        articles = articles.stream()
                .peek(article -> {
                    article.setCategoryName(categoryService.getById(article.getCategoryId()).getName());
                    Integer count = redisCache.getCacheMapValue(SystemConstants.REDIS_VIEW_COUNT_KEY, article.getId().toString());
                    article.setViewCount(count.longValue());
                })
                .collect(Collectors.toList());

        //封装查询vo
        List<ArticleListVo> articleListVos = BeanCopyUtils.copyBeanList(articles, ArticleListVo.class);
        PageVo pageVo = new PageVo(articleListVos,page.getTotal());
        return ResponseResult.okResult(pageVo);
    }

    @Override
    public ResponseResult articleDetail(Long id) {
        Article article = getById(id);
        //从redis获取viewCount
        Integer viewCount = redisCache.getCacheMapValue(SystemConstants.REDIS_VIEW_COUNT_KEY, id.toString());
        article.setViewCount(viewCount.longValue());
        Long categoryId = article.getCategoryId();
        Category category = categoryService.getById(categoryId);
        if(category != null){
            article.setCategoryName(category.getName());
        }
        ArticleDetailVo articleDetailVo = BeanCopyUtils.copyBean(article, ArticleDetailVo.class);
        return ResponseResult.okResult(articleDetailVo);
    }

    @Override
    public ResponseResult updateViewCount(Long id) {
        //更新redis中对应的浏览量
        redisCache.incrementCacheMapValue(SystemConstants.REDIS_VIEW_COUNT_KEY,id.toString(),1);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult add(AddArticleDto articleDto) {
        Article article = BeanCopyUtils.copyBean(articleDto,Article.class);
        save(article);
        List<ArticleTag> articleTags = articleDto.getTags().stream()
                .map(tagId -> new ArticleTag(article.getId(), tagId))
                .collect(Collectors.toList());
        articleTagService.saveBatch(articleTags);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult getArticleList(Integer pageNum, Integer pageSize, String title, String summary) {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        if(StringUtils.hasText(title)){
            queryWrapper.like(Article::getTitle,title);
        }
        if(StringUtils.hasText(summary)){
            queryWrapper.like(Article::getSummary,summary);
        }
        Page<Article> page = new Page<>(pageNum,pageSize);
        page(page,queryWrapper);
        List<Article> articles = page.getRecords();
        List<ArticleAdminVo> articleListVos = BeanCopyUtils.copyBeanList(articles, ArticleAdminVo.class);
        PageVo pageVo = new PageVo(articleListVos,page.getTotal());
        return ResponseResult.okResult(pageVo);

    }

    @Override
    public ResponseResult getArticleById(Long id) {
        LambdaQueryWrapper<ArticleTag> queryWrapper = new LambdaQueryWrapper<>();
        Article article = getById(id);
        queryWrapper.eq(ArticleTag::getArticleId,article.getId());
        ArticleEditVo articleEditVo = BeanCopyUtils.copyBean(article, ArticleEditVo.class);
        List<ArticleTag> articleTags = articleTagService.list(queryWrapper);
        List<Long> tags = articleTags.stream().map(ArticleTag::getTagId).collect(Collectors.toList());
        articleEditVo.setTags(tags);
        return ResponseResult.okResult(articleEditVo);
    }

    @Override
    public void edit(ArticleDto articleDto) {
        Article article = BeanCopyUtils.copyBean(articleDto, Article.class);
        //更新博客信息
        updateById(article);
        //删除原有的 标签和博客的关联
        LambdaQueryWrapper<ArticleTag> articleTagLambdaQueryWrapper = new LambdaQueryWrapper<>();
        articleTagLambdaQueryWrapper.eq(ArticleTag::getArticleId,article.getId());
        articleTagService.remove(articleTagLambdaQueryWrapper);
        //添加新的博客和标签的关联信息
        List<ArticleTag> articleTags = articleDto.getTags().stream()
                .map(tagId -> new ArticleTag(articleDto.getId(), tagId))
                .collect(Collectors.toList());
        articleTagService.saveBatch(articleTags);

    }

    @Override
    public ResponseResult deleteArticleById(Long id) {
        boolean flag = removeById(id);
        if(flag){
            return ResponseResult.okResult();
        }
        return ResponseResult.errorResult(100,"未删除");
    }
}
